
/* $Id: tasto.c 8 2009-12-27 16:54:50Z calicant $ */

#include "edilana.h"

#ifdef AMIGA

#ifdef __AROS__

#include <proto/dos.h>

unsigned char tasto() { 

#define DELTA 44

   unsigned char ch;
   BPTR in = Input();

   Flush(Output());
   SetMode (in, 1); /* set to RAW mode */
   Read (in, &ch, 1);

   if (ch == 155) {
    Read(in, &ch, 1);
    ch = ch - DELTA;
   }   
   SetMode (in, 0); /* set to CON mode */

return ch;
}

#else


#include <exec/types.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <dos/dos.h>

/*
 * le seguenti due funzioni di rilevamento tasto sono state tratte dalla parte amiga
 * dei sorgenti di unzip 5.40
 */

LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs)
{

    LONG count, *pargs, res1;


    struct MsgPort *replyport;
    struct StandardPacket *packet;
 

    replyport = CreatePort(NULL,0L);
    if( !replyport ) return(0);


    packet = (struct StandardPacket *)AllocMem(
            (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
    if( !packet )
    {
        DeletePort(replyport);
        return(0);
    }

    packet->sp_Msg.mn_Node.ln_Name  = (char *)&(packet->sp_Pkt);
    packet->sp_Pkt.dp_Link          = &(packet->sp_Msg);
    packet->sp_Pkt.dp_Port          = replyport;
    packet->sp_Pkt.dp_Type          = action;

    /* copy the args into the packet */
    pargs = &(packet->sp_Pkt.dp_Arg1);      /* address of 1st argument */
    for( count=0; count<nargs; count++ )
        pargs[count] = args[count];

    PutMsg(pid,(struct Message *)packet);   /* send packet */

    WaitPort(replyport);
    GetMsg(replyport);

    res1 = packet->sp_Pkt.dp_Res1;

    FreeMem((char *)packet,(long)sizeof(*packet));
    DeletePort(replyport);

    return(res1);

} /* sendpkt() */




unsigned char agetch (void) {
   
    struct Task *me = FindTask(NULL);  
    struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI);  
    BPTR fh = cli->cli_StandardInput;   /* this is immune to < redirection */  
    void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type;  
    char longspace[8];  
    long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */  
    unsigned char c;  

    fflush(stdout);
    *flag = 1;  
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);         /* assume success */  
    Read(fh, &c, 1);  
    *flag = 0;  
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);  
    if (c == 3)                                         /* ^C in input */  
        Signal(me, SIGBREAKF_CTRL_C);

    return c;  
}  


unsigned char tasto ()
{
unsigned char ch;
#define DELTA   44

    ch = agetch();

    if (ch != 155)
        ;
    else
        ch = agetch() - DELTA;

return ch;
}
#endif
#endif

#ifdef __MSDOS__
#include <conio.h>

char tasto (void)
{
#define DELTA 71

static char conv[] = {
/*71*/  1, 21, 20, 0, 24, 0, 23, 0, 5, 22, 12, 0, 8
};

char ch0, ch;

    ch0 = getch();
    if (ch0) return ch0;
    else ch = getch();

        if (ch > 70 && ch < 84)
        ch = conv[ch-DELTA];

return ch;
}

#endif

#ifdef __unix__
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#ifndef __APPLE__
    #include <termio.h>
#endif
#include <termios.h>
#include "tasti.h"

#define LMAX 1024

#ifdef __APPLE__
    #define TCGETA  TIOCGETA
    #define TCSETA  TIOCSETA

static struct termios term_orig;
#else
static struct termio term_orig;
#endif

static int  kbdflgs;
static char w__S[16][LMAX];
static int  j__S = 0;
static int  i__x = 0;

static int system_mode (void)
{
    if (ioctl(0, TCSETA, &term_orig) == -1)
        return 0;
    fcntl(0, F_SETFL, kbdflgs);
}

static int input_mode (void)
{
#ifdef __APPLE__
static struct termios term;
#else
static struct termio term;
#endif

static int flags;

    if (ioctl(0, TCGETA, &term) == -1)
        return -1;
    (void) ioctl(0, TCGETA, &term_orig);
    term.c_iflag = 0;
    term.c_oflag = 0;
    term.c_lflag = 0;
    term.c_cc[VMIN] = 1;
    term.c_cc[VTIME] = 0;
    if (ioctl(0, TCSETA, &term) == -1)
        return -1;

    kbdflgs = fcntl(0, F_GETFL, 0);
    flags = fcntl(0, F_GETFL);
    flags &= ~O_NDELAY;
    fcntl(0, F_SETFL, flags);

return 0;
}

static char *INKEY_S (void)
{
int i;

    if (++j__S == 16)
        j__S = 0;
    input_mode();
    while((i = read(0, w__S[j__S], 5)) < 1) ;
    w__S[j__S][i] = 0;
    system_mode();
    if (w__S[j__S][0] == 3)
        exit(0);

return w__S[j__S];
}



char tasto (void)
{
static int i, j;
static char a_S[LMAX];



    fflush(stdout);
    strcpy(a_S, INKEY_S());

    if (a_S[0] == 27 && a_S[1] == 91)
        switch(a_S[2]) {
            case 65:
                return CURS_UP;
            case 66:
                return CURS_DOWN;
            case 67:
                return CURS_RIGHT;
            case 68:
                return CURS_LEFT;
            default:
                return 0;
        }

return a_S[0];
}
#endif
